namespace C1.Win.C1FlexGrid
{
    using C1.Win.C1FlexGrid.Util.Styles;
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Reflection;

    public abstract class RowColCollection : IEnumerable
    {
        internal int _defaultSize;
        internal bool _dirty;
        internal int _fixed;
        internal int _frozen;
        internal GridModel _grid;
        internal ArrayList _items;
        internal int _lastVisible;
        internal int _maxSize;
        internal int _minSize;

        protected RowColCollection()
        {
        }

        internal Style AddStyle()
        {
            return this._grid._styles.AddInternal();
        }

        public bool Contains(RowCol item)
        {
            return this._items.Contains(item);
        }

        public IEnumerator GetEnumerator()
        {
            return this._items.GetEnumerator();
        }

        internal int GetItemAt(int pos)
        {
            int num = 0;
            int count = this._items.Count;
            if ((pos < 0) || (count == 0))
            {
                return -1;
            }
            RowCol col = this[count - 1];
            if (pos > col.End)
            {
                return -100;
            }
            if (pos < col.Beg)
            {
                while (count > num)
                {
                    int num3 = (num + count) / 2;
                    col = this[num3];
                    int beg = col.Beg;
                    if (beg > pos)
                    {
                        count = num3;
                    }
                    else
                    {
                        num = num3;
                    }
                    if ((beg <= pos) && ((beg + col.SizeDisplay) > pos))
                    {
                        return num3;
                    }
                }
                return num;
            }
            return (count - 1);
        }

        internal int GetLastVisible()
        {
            if (this._dirty)
            {
                this.Update();
            }
            return this._lastVisible;
        }

        internal Style GetStyle(CellStyleEnum se)
        {
            return this._grid._styles[se]._style;
        }

        internal bool IsFixed(int index)
        {
            return (index < this._fixed);
        }

        internal bool IsFrozen(int index)
        {
            return (index < (this._fixed + this._frozen));
        }

        public virtual void Move(int indexOld, int indexNew)
        {
            if (indexNew != indexOld)
            {
                if ((indexNew < 0) || (indexNew >= this._items.Count))
                {
                    throw new ArgumentException("Cannot move row/column, new index is out of range.");
                }
                RowCol col = this[indexOld];
                this._items.RemoveAt(indexOld);
                this._items.Insert(indexNew, col);
                this.SetDirty();
            }
        }

        public virtual void MoveRange(int index, int count, int indexNew)
        {
            if ((index != indexNew) && (count >= 1))
            {
                if ((index + count) > this._items.Count)
                {
                    throw new ArgumentException("Bad arguments in MoveRange command (index+count > list size)");
                }
                if ((indexNew < 0) || (indexNew > (this._items.Count - count)))
                {
                    throw new ArgumentException("Bad arguments in MoveRange command (indexNew is out of range)");
                }
                ArrayList c = new ArrayList(count);
                for (int i = 0; i < count; i++)
                {
                    c.Add(this._items[index + i]);
                }
                this._items.RemoveRange(index, count);
                this._items.InsertRange(indexNew, c);
                this.SetDirty();
            }
        }

        internal void NotifyViews(GridChangedTypeEnum action)
        {
            this.NotifyViews(action, -1, -1, -1, -1);
        }

        internal void NotifyViews(GridChangedTypeEnum action, int row, int col)
        {
            this.NotifyViews(action, row, col, row, col);
        }

        internal void NotifyViews(GridChangedTypeEnum action, int r1, int c1, int r2, int c2)
        {
            if (this._grid != null)
            {
                this._grid.NotifyViews(action, r1, c1, r2, c2);
            }
        }

        internal void SetDirty()
        {
            if (this._fixed < 0)
            {
                this._fixed = 0;
            }
            if (this._fixed > this._items.Count)
            {
                this._fixed = this._items.Count;
            }
            if (this._frozen < 0)
            {
                this._frozen = 0;
            }
            if (this._frozen > (this._items.Count - this._fixed))
            {
                this._frozen = this._items.Count - this._fixed;
            }
            this._dirty = true;
        }

        internal virtual void Update()
        {
            if (this._dirty)
            {
                int num = 0;
                RowCol col = null;
                foreach (RowCol col2 in this._items)
                {
                    col2._offset = num;
                    if (((short) (col2._flags & RowColFlags.Hidden)) == 0)
                    {
                        num += col2.SizeDisplay;
                        col = col2;
                    }
                }
                this._lastVisible = (col == null) ? -1 : col.Index;
                this._dirty = false;
            }
        }

        public virtual int Count
        {
            get
            {
                return this._items.Count;
            }
            set
            {
                throw new ApplicationException("Cannot set in base class.");
            }
        }

        public int DefaultSize
        {
            get
            {
                return this._defaultSize;
            }
            set
            {
                if (this._defaultSize != value)
                {
                    if (value < 0)
                    {
                        value = 0;
                    }
                    this._defaultSize = value;
                    this.SetDirty();
                    this.NotifyViews(GridChangedTypeEnum.GridChanged);
                }
            }
        }

        [DefaultValue(1)]
        public virtual int Fixed
        {
            get
            {
                return this._fixed;
            }
            set
            {
                if (this._fixed != value)
                {
                    this._fixed = value;
                    this.SetDirty();
                    this.NotifyViews(GridChangedTypeEnum.LayoutChanged);
                }
            }
        }

        [DefaultValue(1)]
        public virtual int Frozen
        {
            get
            {
                return this._frozen;
            }
            set
            {
                if (this._frozen != value)
                {
                    this._frozen = value;
                    this.SetDirty();
                    this.NotifyViews(GridChangedTypeEnum.LayoutChanged);
                }
            }
        }

        internal RowCol this[int index]
        {
            get
            {
                return (RowCol) this._items[index];
            }
        }

        [DefaultValue(0)]
        public int MaxSize
        {
            get
            {
                return this._maxSize;
            }
            set
            {
                if (this._maxSize != value)
                {
                    this._maxSize = value;
                    this.SetDirty();
                    this.NotifyViews(GridChangedTypeEnum.GridChanged);
                }
            }
        }

        [DefaultValue(0)]
        public int MinSize
        {
            get
            {
                return this._minSize;
            }
            set
            {
                if (this._minSize != value)
                {
                    this._minSize = value;
                    this.SetDirty();
                    this.NotifyViews(GridChangedTypeEnum.GridChanged);
                }
            }
        }
    }
}

